#!/bin/bash

OCCA_DIR=$(cd $(dirname "$0")/.. && pwd)
EXAMPLE_DIR="${OCCA_DIR}/examples"

export ASAN_OPTIONS
ASAN_OPTIONS+=':protect_shadow_gap=0'
ASAN_OPTIONS+=':detect_container_overflow=0'

HEADER_CHARS=80

export LD_LIBRARY_PATH="${OCCA_DIR}/lib:${LD_LIBRARY_PATH}"
export DYLD_LIBRARY_PATH="${OCCA_DIR}/lib:${DYLD_LIBRARY_PATH}"

declare -a examples=(
  cpp/01_add_vectors
  cpp/02_background_device
  cpp/03_inline_okl
  cpp/04_reduction
  cpp/05_building_kernels
  cpp/06_unified_memory
  cpp/07_dtypes
  cpp/08_arrays
  cpp/09_streams
  cpp/11_native_cpp_kernels
  cpp/12_native_c_kernels
  c/01_add_vectors
  c/02_background_device
  c/03_inline_okl
  c/04_reduction
)

failed_examples=""
for mode in $("${OCCA_DIR}/bin/occa" modes); do
    case "${mode}" in
        Serial) device="mode: 'Serial'";;
        OpenMP) device="mode: 'OpenMP'";;
        CUDA)   device="mode: 'CUDA', device_id: 0";;
        OpenCL) device="mode: 'OpenCL', platform_id: 0, device_id: 0";;
        Metal) device="mode: 'Metal', device_id: 0";;
    esac

    for example_dir in "${examples[@]}"; do
        flags=(--verbose --device "${device}")

        # Filters
        case "${example_dir}" in
            # OpenCL + Shared memory is finicky
            # OpenCL throws CL_DEVICE_MAX_WORK_GROUP_SIZE
            cpp/04_reduction)
                if [[ "${mode}" == OpenCL ]]; then
                    continue
                fi;;
            cpp/08_arrays)
                if [[ "${mode}" == OpenCL ]]; then
                    continue
                fi;;
            c/04_reduction)
                if [[ "${mode}" == OpenCL ]]; then
                    continue
                fi;;
            cpp/11_native_cpp_kernels)
                if [[ "${mode}" != Serial ]]; then
                    continue
                fi
                flags=(--verbose)
                ;;
            cpp/12_native_c_kernels)
                if [[ "${mode}" != Serial ]]; then
                    continue
                fi
                flags=(--verbose)
                ;;
        esac

        banner="(${mode}) ${example_dir}"
        chars=$(echo "${banner}" | wc -c)
        linechars=$((${HEADER_CHARS} - ${chars} - 6))
	      line=$(printf '%*s' ${linechars} | tr ' ' '-')
	      echo -e "\n---[ ${banner} ]${line}"

        cd "${EXAMPLE_DIR}/${example_dir}"
        make clean; make

        ./main "${flags[@]}"

        # Check for example failures
        if [ $? -ne 0 ]; then
            failed_examples+="  - ${mode}: ${example_dir}\n"
        fi

        # Test output footer
	      printf '%*s\n' ${HEADER_CHARS} | tr ' ' '='
    done
done

if [[ "${failed_examples}" != "" ]]; then
    echo -e "\n\nFailed examples:"
    echo -e "${failed_examples}"
    exit 1
fi
